package com.hitqz.robot;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Table;
import com.hitqz.robot.api.business.enums.BrandEnum;
import com.hitqz.robot.camera.IEquipmentService;
import com.hitqz.robot.camera.configure.EquipmentCmdEnum;
import com.hitqz.robot.camera.dto.EquipmentParamsDto;
import com.hitqz.robot.camera.dto.IEquipmentCmdParamsDto;
import com.hitqz.robot.camera.dto.IEquipmentCmdResult;
import com.hitqz.robot.camera.dto.QueryParamsDto;
import com.hitqz.robot.dto.AirQualityDto;
import com.hitqz.robot.dto.JackDistanceDto;
import com.hitqz.robot.util.ChipCacheUtil;
import com.hitqz.robot.util.ChipToolKit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author xupkun
 * @date 2024/11/3
 */
@Service("hitChip")
@Slf4j
public class HitChipService implements IEquipmentService {

    private final Table<String, String, String> paramsCacheTable = HashBasedTable.create();

    @Override
    public BrandEnum brand() {
        return BrandEnum.HIT_CHIP;
    }

    /**
     *
     * @return
     */
    @Override
    public boolean intSdk() {
        // 启动端口
        ChipToolKit.init(8081);
        return true;
    }

    @Override
    public boolean setEquipmentParams(QueryParamsDto dto, List<EquipmentParamsDto> paramsDtos, boolean async) {
        try {
            Optional<EquipmentParamsDto> jackDistance = paramsDtos.stream().filter(t -> "jackDistance".equals(t.getKey())).findFirst();
            if (jackDistance.isPresent()) {
                int distance = Integer.parseInt(jackDistance.get().getValue());
                ChipToolKit.setJackDistance(dto.getIp(), distance);
                if (async) {
                    //异步立刻返回
                    return true;
                }
                //同步-检测是否到位
                for (int i = 0; i < 10; i++) {
                    Thread.sleep(1000);
                    List<EquipmentParamsDto> params = this.getEquipmentParams(dto);
                    Optional<EquipmentParamsDto> currentJackDistanceDto = params.stream().filter(t -> "jackDistance".equals(t.getKey())).findFirst();
                    if (currentJackDistanceDto.isEmpty()) {
                        continue;
                    }
                    int currentDistance = Integer.parseInt(currentJackDistanceDto.get().getValue());
                    if (Math.abs(distance - currentDistance) < 5) {
                        log.info("[chip]到位");
                        break;
                    }
                    //外部中断标志
                    if (ChipCacheUtil.getStopFlag()) {
                        log.info("[chip]外部中断,退出到位判断循环");
                        break;
                    }
                }
            }
            return true;
        }catch (Exception e){
            log.error("[chip]set param error,{}",e.getMessage());
            return false;
        }
    }

    @Override
    public List<EquipmentParamsDto> getEquipmentParams(QueryParamsDto dto) {
        List<EquipmentParamsDto> paramsDtos = Lists.newArrayList();
        // 推杆/ 顶升高度
        if (ChipToolKit.findByIpAddress(dto.getIp() )== null) {
            throw new IllegalArgumentException("设备未连接");
        }
        // 空气质量数据
        Map<String ,Object> ret = (Map<String, Object>) ChipCacheUtil.get(ChipCacheUtil.KEY_AIR_QUALITY);
        if (ret != null) {
            AirQualityDto lastAirQuality = (AirQualityDto) ret.get(dto.getIp());

        }
        // 高度
        Map<String ,Object> jackDistance = (Map<String, Object>) ChipCacheUtil.get(ChipCacheUtil.KEY_JACK_DISTANCE);
        if (jackDistance != null) {
            JackDistanceDto jackDistanceDto = (JackDistanceDto) jackDistance.get(dto.getIp());
            paramsDtos.add(new EquipmentParamsDto("顶升绝对高度(mm)",
                    "jackDistance", String.valueOf(jackDistanceDto.getJackDistance()), ""));
        }
        return paramsDtos;
    }


    @Override
    public List<EquipmentParamsDto> getDeviceParamsData(QueryParamsDto dto, EquipmentCmdEnum cmdEnum) {
        //获取自定义的姿态
        String pose = paramsCacheTable.get(dto.getIp(), cmdEnum.getDesc());
        if (StrUtil.isNotBlank(pose)){
            try {
                List<EquipmentParamsDto> equipmentParamsDtos = JSONArray.parseArray(pose, EquipmentParamsDto.class);
                if (!equipmentParamsDtos.isEmpty()){
                    return equipmentParamsDtos;
                }
            }catch (Exception e){
                log.error("[chip] parse pose array error {}",e.getMessage());
            }
        }
        List<EquipmentParamsDto> paramsDtos = Lists.newArrayList();
        paramsDtos.add(new EquipmentParamsDto("顶升高度", "jackDistance", "0", ""));
        return paramsDtos;
    }


    @Override
    public IEquipmentCmdResult executeCmd(QueryParamsDto dto, boolean ansyc, EquipmentCmdEnum cmdEnum, IEquipmentCmdParamsDto cmdParamsDto) {
        switch (cmdEnum){
            case JACKING_UP->{
                //获取当前高度
                Map<String ,Object> jackDistance = (Map<String, Object>) ChipCacheUtil.get(ChipCacheUtil.KEY_JACK_DISTANCE);
                if (jackDistance != null) {
                    JackDistanceDto jackDistanceDto = (JackDistanceDto) jackDistance.get(dto.getIp());
                    //设置高度
                    ChipToolKit.setJackDistance(dto.getIp(), jackDistanceDto.getJackDistance()+20);
                }
            }
            case JACKING_DOWN -> {
                //获取当前高度
                Map<String ,Object> jackDistance = (Map<String, Object>) ChipCacheUtil.get(ChipCacheUtil.KEY_JACK_DISTANCE);
                if (jackDistance != null) {
                    JackDistanceDto jackDistanceDto = (JackDistanceDto) jackDistance.get(dto.getIp());
                    //设置高度
                    ChipToolKit.setJackDistance(dto.getIp(), jackDistanceDto.getJackDistance()-20);
                }
            }
        }
        return null;
    }

    @Override
    public boolean motionAbort(QueryParamsDto dto) {
        ChipCacheUtil.setStopFlag();
        return true;
    }

    public Table<String, String, String> getParamsCacheTable(){
        return  paramsCacheTable;
    }

}
